﻿using System;
using System.Security.Principal;
using System.Web;
using System.Web.Script.Serialization;
using System.Web.Security;
using DemoLib.Shared.Models;

namespace Mvc4Demo.Core
{
    public static class AuthenticationProcessor
    {

        public static void SetAuthenticationTicket(this HttpContextBase httpContext, User user)
        {
            var ticket = new UserTicket
                             {
                                 Name = user.UserName,
                                 Role = user.Role.RoleName,
                                 Id = user.Id
                             };

            var jsonSerializer = new JavaScriptSerializer();

            var userData = jsonSerializer.Serialize(ticket);

            var authTicket = new FormsAuthenticationTicket(1, user.UserName, DateTime.Now, DateTime.Now.AddHours(1), false, userData);

            string encryptedTicket = FormsAuthentication.Encrypt(authTicket);

            var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);

            httpContext.Response.Cookies.Add(authCookie);
        }

        public static void AuthenticationTicket(this HttpContext httpContext)
        {
            HttpCookie authCookie = httpContext.Request.Cookies[FormsAuthentication.FormsCookieName];

            if (authCookie == null || string.IsNullOrEmpty(authCookie.Value))
                return;

            try
            {
                FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
                
                var jsonSerializer = new JavaScriptSerializer();

                var ticket = jsonSerializer.Deserialize<UserTicket>(authTicket.UserData);

                var demoIdentity = new DemoIdentity(ticket.Name)
                                       {
                                           User = ticket,
                                       };

                httpContext.User = new DemoPrincipal(demoIdentity);
            }
            catch (Exception ex)
            {

            }
        }

        public class DemoPrincipal : IPrincipal
        {
            private readonly DemoIdentity _loyaltIdentity;

            public DemoPrincipal(DemoIdentity loyaltIdentity)
            {
                _loyaltIdentity = loyaltIdentity;
            }
            public bool IsInRole(string role)
            {
                return role.Contains(_loyaltIdentity.User.Role);
            }

            public IIdentity Identity { get { return _loyaltIdentity; } }

            public DemoIdentity LoyaltIdentity { get { return _loyaltIdentity; } }
        }

        public class DemoIdentity : IIdentity
        {
            public DemoIdentity(string name)
            {
                Name = name;
            }

            public string Name { get; private set; }
            public string AuthenticationType { get { return "Custom"; } }
            public bool IsAuthenticated { get { return true; } }

            public UserTicket User { get; set; }

        }

        public class UserTicket
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public string Token { get; set; }
            public string Role { get; set; }
        }
    }
}